One little gem I found in the book was a comment about portability. As the book points out, there are two ways you can write portable code, which they call the "union" approach and the "intersection" approach.
The union approach is to write compatibility shims over the platform-specific interfaces that each platform gives you. The intersection approach is to use only APIs that are provided by all the platforms you intend to support.
A lot of programmers intuitively reach for the union approach. The platform-specific APIs are often nicer and more powerful than the cross-platform ones. However, Kernighan and Pike favor the intersection approach. As they point out, it results in fewer lines of code, which translates into less that you need to test.
I have to admit, they are probably right. If you can, use the intersection approach to portability, and save yourself a lot of grief down the road.
Of course, you have to be judicious about adding a new library to your project. In general, I tend to reject libraries that introduce a huge set of unecessary dependencies, are inefficient, or try to solve too many unrelated problems. The ideal library just does one thing, and does it very well.
Even well-written libraries have limitations. For example, libev doesn't perform very well on Microsoft Windows. This is not really the fault of the author, but just a reflection of the fact that file descriptors are second-class citizens on Windows. In order to get optimal performance on Windows, you would have to use completion ports, which have a totally different API.
So in summary: don't be too quick to write compatibility shims. First, see if you can make do with the APIs that are available to you on every platform. If you do decide you need the shims after all, see if anyone else has produced a good library to fill that role.