Technical debt is a hard problem. But that kind of problems has sometimes surprising solutions, where one leaves a local optimum to find a better optimum point.
What kind of smart strategies did you find to reduce technical debt in relatively new code bases?
As an aside, in the last time, I have heard several times that using new programming languages / language standards like C++20 or Python 3.10 helps against technical debt. I am not so sure about that one. Sure, code bases with new language versions or standards are overall newer, and therefore, they tend to have less technical debt. This is quite logical to me. But my impression is that good practice and experience is what makes the crucial difference seven of eight years later. In fact, I suspect that languages that are evolving rapidly might accumulate more technical debt, as they are less stable by concept.
All this is superimposed with business fields where few codebases are older than some three years (like typical start-ups) and others where a vast amount of code runs 20 years or more (like industrial automation and banking). And there are even some communities which are using rather old languages because of their (real or perceived) stability.
It is not technical debt if there is no explicit decision, or it is the gradual and continuous bitrot that all codebases suffer. I usually refer to this as cruft and while good design and writing code to optimise for readability / understandability reduce the rate that cruft accumulates, it cannot be stopped due to the nature of software. The best practice I have found to fight cruft is many small refactorings and cleanups as part of every piece of work I deliver. This strategy is outlined in https://ronjeffries.com/xprog/articles/refactoring-not-on-th....