Option 2 is significantly slower.
In Option 1, using the 'for each' loop is equivalent to using an iterator to access the List.
It's a read-only access and doesn't require any extra storage in memory, nothing need to be copy and pasted nor take any space on the memeory, so it's not generating any 'waste'. Click here to learn about How does the Java 'for each' loop work?
Compare to Option 2, you created a new object just to be garbage collected when you do this.
String output = "";
As well as every time when this
output = output + s + "\n";
happens, a new String object is created, and copy and pasted from the older one. And the reference 'output' moved on to work for the new String object, leaving the old one sitting alone in the memory, waiting to be garbage collected. This happens because the property of java String, it's immutable meaning once it's created, it can never be changed. aka all String are created final. Learn more about Immutability of Strings in Java
As of the System.out.println() function, it will only take constant time, so in terms of Big O notation analysis, it's neglect-able.
This question is a very good example why you should use StringBuilder or StringBuffer to manipulate String in java. Why StringBuilder when there is String?