I've talked quite a bit about code smells over the course of my career. My Refactoring Fundamentals and Azure Refactoring courses on Pluralsight both discuss the topic, with the former going into great depth and covering literally dozens of code smells. The course is over 8 hours long, but it not only demonstrates tons of code smells but also shows how to refactor to improve your code in response to them.
It's important to note that code smells represent things in your code that are potentially bad. They should catch your attention, and you should think about whether, in context, the smell in question is acceptable or not. Sometimes, it's perfectly fine, or it's not worth the effort to refactor to a different design.
If you've never heard of the term code smell, I encourage you to look into it. There are some links in the show notes for this episode. One benefit of learning about code smells mirrors a benefit of learning about design patterns, which is that these named smells allow you to identify and communicate concepts quickly with other developers. For example, if you're discussing some code and mention it seems to have 'primitive obsession', that term refers to a specific code smell which is well-documented and which has certain known refactoring approaches. By using this term, you convey a lot of information in just two words that otherwise might have required a great deal more explanation.
It can be useful as well to learn about different categories of code smells. These categories include things like Bloaters, Obfuscators, and Couplers, as well as smells specific to kinds of code, like testing smells. These categories help as you're learning about code smells because they let you see a variety of smells that all have similar impacts on the code. Bloaters tend to result in code becoming larger than necessary. Couplers introduce unnecessary coupling into the application. Obfuscators make it more difficult to quickly understand how some part of your application works. And test smells make tests more difficult to write and maintain, or less reliable when run.
Some code smells you can identify with static code analysis tools, like NDepend. For instance, you can easily write a query in NDepend to return all methods over a certain number of lines of code. These kinds of tools can help you identify potential problem areas in your code so you can better direct your refactoring efforts.
I may dive into some different code smells, and how to correct them, in future tips. In the meantime, if you want to get up to speed the best resource I can recommend is my Refactoring Fundamentals course, on Pluralsight.