I'm rather partial to Wikipedia's summary myself:
A legacy system is an old method, technology, computer system, or application program that continues to be used, typically because it still functions for the users' needs, even though newer technology or more efficient methods of performing a task are now available.
A lot of what other people are describing in their answers are reasons why code becomes "legacy". But the essential question itself is this:
But it's still used in the production systems - so is it really legacy? And what makes it legacy?
The fact that it is still used in production is precisely what makes it legacy. If the code does not work properly, or is no longer used in production, then that code is "broken" or "retired", respectively. Legacy means that it is still in use and works fine, but incorporates designs or techniques that are no longer in common use.
Any code or system that you either (a) would like to upgrade/update, but can't, or (b) are still in the middle of upgrading, is a legacy system. This doesn't mean refactoring or general code cleanup, it means significant changes to the design, possibly using a new framework or even a new platform.
There are any number of reasons why systems or code might become legacy:
Lack of regular maintenance or software rot. Clearly if the application is not maintained regularly, it will not keep pace with major changes in the software world. This might be due to simple neglect or it might be a deliberate choices based on business priorities or budgetary constraints.
Lack of testing. Another answer references a popular author's hyperbolic claim of any code not covered by tests being legacy code. This really isn't an accurate definition but it is a possible root cause; without good tests (automated or manual), developers become timid and afraid to make major changes because they worry about breaking something, thus leading the "software rot" above.
Rev-locking, an often-overlooked factor which is particularly insidious in projects using large open-source libraries or frameworks (although I've seen it happen with commercial tools as well). Often there will be major customization done to the framework/library, making an upgrade prohibitively difficult or expensive. Thus the system becomes legacy because it runs on an older (and possibly no-longer-supported) platform.
The source code is no longer available, meaning that the system can only ever be added to, never changed. Since these systems have to be rewritten in order to upgrade - as opposed to incrementally/iteratively revised - many companies won't bother.
Anything that slows or stops updates to a code base can lead to that code base becoming legacy.
Now the separate, unstated-but-implied question is, what's wrong with legacy code? It's often used as a pejorative term, hence the question:
Should we shy away from this unwarranted labelling of perfectly functioning code?
And the answer is no, we shouldn't; the labeling is warranted and the term itself clearly implies functioning code. The point is not that it's function, but how it's functioning.
In some cases there's nothing wrong with legacy code. It's not a bad word. Legacy code/systems are not Evil. They've just collected some dust - sometimes a little, sometimes a lot.
Legacy becomes obsolete when the system can no longer serve (all of) the client's needs. That label is one that we need to be careful of. Otherwise, it's simply a cost/benefit equation; if the cost of upgrading would be lower than the cost of its benefits (including lower future maintenance costs) then upgrade, otherwise, leave it alone. No need to spit out the word "legacy" in the same tone you normally reserve for "tax audit". It's a perfectly OK situation to be in.