Let us schedule a meeting
Not sure if I should review it as a programming challenge, or if I should include design remarks, I'll just say what comes to mind.

I'll first note that I would make the Meeting fields private final, and add accessor methods. Them being immutable makes sense I would say, and methods help for using them as method references with the streaming API and others, as I will show in a second.

For mergeMeetings, I would really refrain from using set and remove, at least when you do not know the implementation. Depending on the List implementation, the performance of these could turn out to be quite horrible (e.g. set could traverse the list up to the index each time in case of a LinkedList). Also looping and mutating a collection at the same time is a lot of times error-prone or worse. Finally, you mutate the collection passed in, which is also a point to think about twice (though not necessarily bad).

For mergeMeetings2, I like this implementation better. It is a smarter implementation for given problem. First, I would like to note that since Java 8, Collection has a default method implementation for sort. Next, with the Comparator#comparing method, you can specify which property of the type to use to compare with. If you add accessor methods like stated before, this would make the sort look like (with a static import of Comparator):

meetings.sort(comparingInt(Meeting::startTime));


Perhaps instead of using a List to keep track of the merged meetings, you could use a stack (though do not use Stack, rather something like ArrayDeque, refer to the docs why). Instead of getting the last element from the list, you just peek the top, and pop if you have to merge again. I am not sure how I feel about 

if (merged.isEmpty()) {
    merged.add(current);
    continue;
}


I think it makes the loop implementation a bit confusing, because this is only called once to add the first element to the merged elements. I wonder if using List#subList and iterating over that would be better, or a manual iterator... Also, should the Meetings become immutable, it would change the implementation a bit. Note that you are now changeing objects which are coming from the outside.

Your merge method assumes that the start time of first is always the smallest start time, and that the end time of second is always the greatest start time. This would be wrong for e.g. first = [8, 12], second = [9, 10]. It will return [8, 10], when it should be [8, 12].

The overlaps method also is a bit incorrect, because multiple meetings starting at the same point in time will not be merged. Also (first.endTime == second.startTime || second.startTime &lt; first.endTime) is the same as second.startTime &lt;= first.endTime.

Finally, your show method ends each line with a comma. Should you want to simply delimit each meeting with a comma, but not one at the end of the line, you could solve it for example as:

System.out.println(meetings.stream().map(Meeting::toString).collect(joining(",")));