formatting strings in Arduino for output
If you need the result in a single string then your 3rd option is the preferred way. 

If you don't, then the first option of printing each part separately is the most efficient in terms of memory.

The second version, String concatenation, is the worst option in all respects and should be avoided at all costs.

I often use sprintf to a buffer if I need a specific format (for instance leading zeroes on a number).

If you want to avoid the extra code bloat of sprintf you can use various combinations of strcpy, strcat and itoa etc to build up a string into a memory buffer (if you really need to put it in a buffer).

Note that on an 8-bit Arduino sprintf has no float support - so you would still need to use dtostrf to format a float into a char buffer first, or print it directly.