Code Complete, 2nd edition. It’s about the construction of software and the design that goes in the small parts of the code you write. The book is huge, so reading it might take a while, but it’s still very relevant and useful.
The Clean series (Code, Coder, Architecture), those 3 books deal with different aspects of the profession, but I enjoyed all 3 and learned many important lessons from them.
The pragmatic programmer, a book full of important lessons and ideas, it’s a relatively quick read compared to the other books on the list, but the lessons are as valuable.
The mythical man-month, it might be the most important book on the list, full of important lessons about the lifecycle of a software project and the profession itself. I believe Fred Brooks said everything decades ago and we still make the same mistakes.
Design Patterns: Elements of Reusable Object-Oriented Software(GOF): It’s the original design-patterns book, a bit old but still an excellent reference. Being familiar with design patterns gives you a good toolbox for tackling most design challenges, even if the pattern doesn’t match your problem perfectly, you have a solid base for building a solution.
Head First Design Patterns(Robson and Freeman): I think this one is much easier to digest than the GOF book. Read both, maybe start with this one and when you become familiar with the contents use the GOF book as a reference.
Practical Object-Oriented Design: An Agile Primer in Ruby(Sandi Metz): It’s more hands-on than the other ones, full of examples and refactoring. It starts with an introduction to design thinking and why it’s important to spend time and effort on good architecture and design. Don’t let the ruby part discourage you from using it, the lessons you’ll learn are applicable to all other OO languages.
Domain Driven Design(Evans): DDD is a very useful approach, and it pays off to be familiar with it. Reading this one will go a long way in helping you devise solutions that match well the domain problem and are easy to evolve.