I think all good developers are aware of the basic axiom of "don't repeat yourself" - avoiding writing similar code over and over by making the effort to design and refactor what you've got so it handles all of your use cases.
Where we're not so good is being able to apply the same principles across an organisation. Conway's Law strikes, and for a company with n development teams there will generally be around n different attempts to implement broadly similar functionality. This sometimes happens even when there's a notional "core engineering" team... who spend their time creating gold-standard versions of common libraries that then get used by one project at best.
Why does this happen?
Well, the most common thing I hear is, "we didn't know there was already a library that did it." Followed closely by, "we know team x had a library, but it's not very good/doesn't solve our problem."
The first problem here is that as developers, we're not always good at championing our own work. I've sat in Scrum-of-Scrum meetings (where representatives from multiple teams get together to discuss any overlap or conflict between their work) and had to coax team leads into admitting they'd written code that would solve problems another team were currently encountering. That's wrong; we should have more pride in our craft. We should be jumping on the first opportunity to share our code, rather than hoarding it to ourselves. You shouldn't need the technical architect to point out that you've written something useful!
The second is that we don't really trust anyone else. Neither to write code that we can use, nor to use our own code without needing constant and disruptive support. That's an important attitude to change. When you find something that doesn't meet your standards or doesn't solve exactly the problem you want it to, then refactor it until it does. There's more value in extending an existing library to solve two problems, as chances are the refactoring you do will make it much easier to cover a third requirement in the future, especially compared to having two completely different pieces of code as a starting point. If you take this attitude, then you may find other people are willing to take the same approach with your code, rather than bugging you with requests about it all the time.
(Although as ever, I'd recommend having a decent set of tests so everybody can work with confidence and not inadvertently break functionality. In my experience that's one of the biggest sources of friction between teams working on each other's code, and a direct cause of code hoarding.)
There's one other piece of the puzzle remaining, which is more around the management than the development. Generally, the best time to identify requirements which could be solved by adapting existing code is near the start of the project, when the large-scale layout is being sketched. This requires product managers to keep their teams informed about what's coming up, rather than throwing detailed backlogs over the wall a fortnight before the start date. At the very least this is where a technical architect will be getting involved, with enough knowledge of the moving parts of their software estate to point out potential areas for re-use.
In summary, Don't Repeat Yourself doesn't solely apply to you alone, banging code into a screen. It means making sure your team-mates aren't writing code you've already written, and making sure that other teams aren't duplicating functionality your team already have. No more code hoarding - evangelise your libraries!