Wirth could have figured out a better way to do this, or asked around.
You can have a way for a program to declare the version of the language it wants. Then keywords introduced in all newer versions of the language disappear (are treated as ordinary identifiers).
Via a mechanism like Racket's #lang, Component Pascal could support Oberon-2, Oberon, Modula and even Pascal translation units in the same program.
It does seem as if Wirth operated with serious academic blinders on. He had no concept of treating the language as a product, which supports existing users with dogged backward compatibility. The result was a fragmented landscape of languages, which helped eroded the popularity of the languages.
The C preprocessor has been much maligned, and usually rightfully so, but with the preprocessor, I can take C code that uses C++ keywords like class and new, and make it work. We can easily write a macro convert(type, expr) which will expand to static_cast(expr) when the code is compiled as C++, and to (type) (expr) when compiled as C. C itself has been able to bring in new keywords like bool, true and false without breaking old programs which use these, by requiring programs to include a header from which you get things like #define bool _Bool.
Speaking of C++, most C programs can be easily converted to C++, often with little or no modification. Or at least that used to be true for a long time back in an era when it was important to be able to do that.