Pragmas are machine- or operating system-specific by definition, and are usually different for every compiler. So if you want your code to be portable use the first method.
I've always used both. That way, if #pragma once is supported, it will include the file only once but if not, it is ignored and will used the #ifndef method. I wonder if that would be redundant...?
Not only should you use a unique and predictable (internal) include guard but you should also consider using (external) include guards around each preprocessor include directive in header files.
The following is a small example, both a.h and b.h include base.h but preprocessor will have information to not even visit base.h a second time. It makes little difference on a small project, but a large difference on big ones.
Borland's Turbo Vision (a C++ Text GUI Framework) uses the double guarded style, and so does GNU's autoconfig, although that style uses HAS_xxx, where HAS_xxx is externally defined.
As I said, on small projects you will see not much of a difference.
When the preprocessor is doing it's business and finds an #include, it goes off loads the included file and reads the first line. It finds the guard definition and has a look to see if it is already defined. If it is it still has to process the file until it finds the corresponding #endif and then carry on processing the file to the end.
You may find that your compiler has include guard optimisation, but I have seen results that suggest this can be improved upon.
Feel free to search the net for "external include guards", I have also seen them referred to as "redundant include guards". You should see various peoples experiment results.