If you control the JVM the code is executing in (hosting some user-supplied code), you can install a custom SecurityManager. As described by its documentation, Field.setAccessible will call the installed SecurityManager, which can veto the setAccessible call by throwing SecurityException (or log it or whatever). Unfortunately, the ReflectPermission object passed to the SecurityManager does not contain the Field being granted access, so you can't selectively deny access to particular fields. What you can do is check the call stack (using SecurityManager.getClassContext()) and deny access if any user-supplied code is on the stack.
There may also be a way to enforce this with the default SecurityManager implementation and policy files, but all the examples in the policy file documentation are about granting permission, not revoking it. This would imply you'd have to figure out all the permissions the non-user-supplied code requires and provide appropriate policy files. (Whitelisting is generally a superior security strategy than blacklisting, but requires more effort to set up.)
This is all predicated on the JVM security implementation to work as documented; as you may know, there have been several applet-based exploits that used flaws to escape the JVM sandbox. It's probably best to not run user-supplied code in the same JVM containing sensitive information, instead relying on OS-level process isolation for security. But taking your question strictly ("Can I detect setAccessible?") the answer is yes, if you control the JVM.
If you don't control the JVM the code is executing in (you gave your code to the user to run on their own), protection is futile. Besides modifying your code before running it to remove the protection, they could simply run on a modified JVM that doesn't enforce access checks for reflective operations originating in their code, or that directly modifies whatever fields you're trying to protect.