Buffer concatenation method
If you're optimizing for performance it does not get much better than that. In particular it is a valuable optimization to compute the exact result array length.

I'm not sure why you used ConstrainedCopy which is a very esoteric feature. Copy is faster. ConstrainedCopy is, I believe, used for code that must not be interrupted by a ThreadAbortException. The concept is called a constrained execution region and it's useless in practice because programming in the presence of thread aborts is essentially impossible. The consensus is to never abort a thread except your own (ASP.NET violates that rule which must be very unsafe).

The code is of good quality as well. I'd use foreach to traverse the list. It compiles to the same code that you wrote but is nicer.

Answers have been proposed that use List&lt;byte&gt; or LINQ. These will be far slower (e.g. 10-100x). This is because Array.Copy is a facade over memmove (which is similar to memcpy but it handles overlapping regions as well). The difference becomes noticeable even with common network speeds (10MB/s) and certainly with disk speeds (100MB/s and up).

If you don't care about performance or the amount of data processed is small than you can use slower approaches. Some people find such code better and I'd certainly understand why. The LINQ approach using Concat is extremely concise and self-documenting.