Having spent quite a bit of time and effort dealing with and maintaining library code (openGLCD) that must be aware of board specific differences, my advice is try very very hard to avoid having to do that. It is an endless hole you can get sucked down into that depending on your needs, can get complicated and difficult to maintain.
Try very very hard not to base things based on board type - use something else whenever possible.
You must make sure to have reliable defines that are at the appropriate level to detect the differences and those defines can vary depending on the IDE, the core and the board.
If you must detect differences, try to use the highest level define possible,
i.e. favor using a processor architecture over a specific processor type, and try at all costs not to depend on an Arduino board type.
If possible try to use a define that is not defined by the Arduino IDE
i.e. try to use internal gcc defines whenever possible.
AVR is an example of a gcc define.
For example, there can be some major issues when trying to play games or automate things using a processor architecture type when the differences are actually within a processor type.
For example board specific pin mappings can vary withing the same processor architecture and even within the same processor type, so using a processor architecture or processor type for that purpose generally has issues.
Trying to automate things for pin mappings is the most difficult since the pin mappings are really controlled by the variant not the board/board-type.
i.e. multiple boards can use the same variant for the pin mappings and the user can add his own board types.
So using board type defines for the purpose of detecting pin mappings will fail should the user create his own board types.
You also can't use processor type or core to know the pin mappings since different boards can have different variants with different pin mappings.
And while the IDE knows the variant, it does not offer that information to the source being compiled. It only offers a define based on the board. For pin mappings, you really want to know the variant at compile time and that information is simply not available from the IDE.
It can usually be detected in other ways, but it is a bit ugly/messy and complicated.
Also, keep in mind that several of these types of architecture/board/core type defines that are defined by the IDE have varied though time in various IDE versions.
In some versions of the IDE a define may be non existent or not useful at all.
Like at one point there was a single define that was defined depending on the board type. That is not useful since there is no way
to do a compile time check on the value of define when it is a string.
This is why I recommend using non IDE defines when possible.
Things have settled down quite a bit with recent IDEs but when creating a library, especially if it is intended to run on multiple
versions of the IDE and multiple cores, you must take all this into consideration.
There also is the consideration if the library will be used in environments that build code using alternate tools (without the Arduino IDE). In that case some of the IDE specific defines may not exist.
What can help identify the defines that the Arduino IDE defines is to turn on the debugging output and look at the command line executions to see what defines the IDE is setting and see what changes when you change cores and boards.
There are other processor specific gcc defines as well that get set based on the specific version of gcc, and processor, but you won't see those on the command line from the IDE as they are set internally by gcc.
I will stress again, try very hard to avoid having to do special things, like conditional compilation, based on the target environment.
If it is required, try to use the highest level define possible and if possible use an internal gcc define vs an IDE define.
And try to avoid using a board define as it will fail when a user creates his own board types.