Are we mixing up compile time decision and run time decisions?
As you have to set the compiler for the correct board/chip the choice of which code to run is a compile-time decision. Setting the board/chip sets some mystical defines which you can use to deine your own. I have this once where I needed some code that run on either my "big" Arduino or the nano and trial-error I got to
That is, my code in the few places where the Serial code neded to be sensitive to which oar it ran on I did something like (not exactly that but using your examples)
And your code will be filled with little ifdef variations. You may choose to make your own function that decides, but this adds another call/return overhead at runtime.
Now if the two boards use the same identical code, ie you have the same IDE settings when you hit "upload", then indeed the decision is at runtime. But y*ou need to sense it at runtime*. I had a similar problem, and I said that pin3 was wired to GND on the one board and to 5V on the other board. The code then was
if (digitalRead(3)==LOW) SerialUSB.print("Hello World");
else /* implied digialRead(3)==HIGH*/ Serial.print("Hello World");