Array<UInt8> is very useful when you need a byte container that can grow (we don't have reallocate on Unsafe(Mutable)(Raw)BufferPointer). Span types are very useful for interfaces but need to be backed by some actual container type; very often that is either Array<UInt8> or Unsafe(Mutable)(Raw)BufferPointer.
(It's worth saying that while reallocation-in-place is often frowned upon by more theoretical types, in practice it's often a big performance win being able to do that.)
Data requires importing Foundation, which isn't true of the other types (this means that there are contexts where Data cannot be used, like in the Swift runtime code itself).
There's no equivalent of withUnsafeTemporaryAllocation for Data.
Being able to append bytes to it (and resize it) is useful in some situations. Being able to easily convert to Span types is also handy. The ability to read arbitrary data out of it, likewise — sometimes you have a bag of bytes and want to read a word or even a struct defined in C out of the raw memory.
Creating temporary storage of this kind is often handy when interacting with C code, hence withUnsafeTemporaryAllocation.
Varies depending on what you're talking about. The Swift Runtime module includes code for parsing ELF, PE-COFF and DWARF that you could look at. There are also applications where it makes sense to use a bag-of-bytes as a ring buffer while doing I/O, or as the backing for another data type (like a String).