In terms of package clashes, a prominent issue is command duplication. As an example, consider
\documentclass{article}
\usepackage{txfonts}
\usepackage{amsmath}
\begin{document}
Lorem ipsum \ldots
\end{document}
And you're probably going to run into problems more often if you write a package that could span an entire document (like a math- or symbol-related package) as opposed to providing something more specialised (like a new tabular-like construction, say).
You can take the following steps to minimise the potential for such clashes with other packages:
Use a namespace for your commands. That is, instead of a command \something, use (say) \Awesome@something for your Awesome package. Examples of packages using this approach include xkeyval and algorithm2e.
Historically using @ in commands was sufficient to identify the content as "internal", but it may be better to tie it to the actual package through a namespace identifier as well.
Create your namespace commands using an interface macro. That is, instead of using \newcommand{\<cmd>} in your style file, define (say) \awesome@newcommand{<cmd>} that creates \Awesome@<cmd>. It will allow you to easily change your mind later, if you decide Awesome wasn't as awesome.
You could also consider writing a \nameuse{<cmd>} equivalent to use your namespace commands.
Another, more recent development, is to use a CamelCase naming convention for command definition, even at the user interface level.
If you know some packages that are incompatible with your foo, write those components that cause the problem using package loading conditionals.