But all of them still contain crucial central parts that have been created decades ago, and famously have not been redone from scratch in their history, unlike, say, Windows or vim.
I don't see what is the principal difference between these pieces of software, and some COBOL-based accounting packages still doing heavy lifting in s bank, while being actively maintained and even receiving new features.
It's the old systems that "just work" until they don't. Where they run on old hardware, and the compiler is possibly on something even older. You can't port them to a new system because you may not have a compiler or even the source code. Or the source code is heavily dependent on the original physical hardware. Maybe it runs in a VM, if it was on an IBM mainframe it probably does. But that doesn't fix the problem of old code that can't be easily altered at this point in time.
I like Michael Feathers' definition of legacy code being code without tests. But it's not just tests, it's comprehensibility and (to a lesser extent) portability. Tests help to make a system comprehensible and portable. Since architecting for testing requires better modularity which makes things both more portable and more comprehensible in most cases. Portability means proper abstraction over the hardware or other things so that the core logic is separable. Imagine if the IRS's tax system were written in this way, where the hard-to-port part would be the interface with databases and networks, but the core part would be easily portable (or more easily portable) to another OS because it'd be properly separated. We could port that core to another system and change how it gets called more easily. But if you tied your software to a specific DB or a specific storage medium (like it has to be a tape drive, or something that behaves like one) you've reduced portability, and created the start of a legacy system.
It is if you're on the most recent working version (3.6).