Why do functions containing `await` need to be `async`?
The async annotation changes the way the body of the function is interpreted. Now you can clearly infer that if the body contains await, it must be async, but there are a couple of reasons why it makes sense to require an annotation.

The primary reason is, frankly, likely clarity. C# popularized this syntax and is a language that emphasizes declaring intent. My understanding (from vague recollections of blog posts) is that the C# designers view the fact that they didn't do a similar thing for generator syntax (i.e. yield) as a mistake or at least unpleasant compromise. Note that in JavaScript you do need to indicate a function is a "generator function" in much the same way as async. At any rate, both async/await and yield lead to dramatically different semantics, and you probably want to be clear that that is intended and understood. (A minor factor for C# was to make the await keyword contextual to avoid backwards compatibility issues.)

As a more technical reason, async and JavaScript's function* change the behavior of a function even if you don't use await/yield. In C#, an async method with no await will run synchronously, but it will still package up the result in a Task object. Similarly, in JavaScript, a generator function with no yield still returns an empty Iterable rather than undefined. If the async/function* aspect was inferred from usage of await/yield, then in these cases you would need to explicitly create a Task or Iterable. This isn't so bad in C# where the type system will require this, but in JavaScript there's a much greater chance for uncaught errors. Regardless, it's also bad for exploration since commenting out a line of code might dramatically change the behavior and type of the function.