While that should work, I would strongly recommend using a prebuilt Mail/SMTP class such as Zend_Mail. While I don't think the whole Zend Framework is the cat's pajamas, I do have a very good opinion of their mail handling code.
EDIT: I should also add that using a prebuilt Mail/SMTP class will abstract almost all of the complexity/structure of multi-part emails.
Are the UTF-8 declarations and attachments well formed?
No. You would want to use quoted_printable_decode() only if you are decoding an email message. Not when you are encoding one. Should you use quoted_printable_encode()? I will discuss this next.
Content-Transfer-Encoding: 7 or 8 bits? I've always seen 7 but since I'm sending a UTF-8 encoded mail I'm not sure.
Only use 8bit encoding if you know that the destination SMTP server can support it. However, since you are passing your email off to the local MTA, I wouldn't recommend setting this value. The default value is 7bit encoding, but it has it's own set of restrictions: up to 998 octets per line of the code range 1-127 with CR and LF only allowed to appear as part of the CRLF line ending (http://tools.ietf.org/html/rfc2045#section-2.7).
If you know you are not going to be handling Multibyte messages (Japanese, Korean, Chinese, etc.) then mail() should suffice.
You are specifying that the Character set of your Plain Text and Html content parts are UTF-8, however it doesn't appear as you are actually ensuring that they really are UTF-8 encoded.
You are checking for null in $to, $bcc, $attachments before you further process them, however, you aren't doing anything when they may actually be null. So, if you happen to receive a null for $to, you don't process the variable, but you continue to send an email to null.
As of right now, that's all I am going to go into but I am still going to highly recommend a pre-built solution as they have had lots of users/time to work out bugs.
I agree, Zend_Mail has everything you need and more! Use a library developed by many people, it usually has less errors in it.
"If you know you are not going to be handling Multibyte messages (Japanese, Korean, Chinese, etc.) then mail() should suffice." - What messages in other languages, such as German, French, Portuguese and Spanish? Does mail() still suffice?
It really comes down to Character Encoding. If you are using UTF-8 for your character encoding (HTTP GET/POST, database, etc.) using mail() will work just fine as it is single byte. UTF-16/UCS-2, on the other hand, are Multibyte, and would require the use of mb_send_mail().