One of the issues I have seen over the years is the number of times that the wheel gets reinvented. In the 90s, there were many good books written about efficient algorithms and useful design patterns, but few of the younger developers seem to have read them.
On the other hand, the rise of plug-in modules is great. If you need to sort an array, rather than writing yet another sort routine (from scratch, since you never read Don Knuth's book on sorting and searching), you can google 'npm sort' and take your pick of efficient and well-debugged modules that you can simply plug into your project. This is a huge step forward (assuming that the person who created the module read some books).
The adoption of agile development has also been a great step forward. I worked on and managed numerous "six month" waterfall projects, including some that turned into year-plus death marches, some that were cancelled after completion because the user's requirements no longer matched the product, and a select few that came in on time and matched the users needs.
About thirteen years ago my small software development company adopted scrum, and since then have consistenly delivered projects that more closely matched the client's needs. Along the way, we also adopted TDD, BDD, etc., all of which really are necessary to deliver on the promise of scrum.